import type { Ref } from 'vue'
import type { NvCrudFieldOption } from '../types'
import type { Emits, FormDone, Props } from './types'
import type { NvFormItemOption, NvFormOption } from '@/form/types'
import type { RowData } from '@/types'
import { computed, useId } from 'vue'
import { useLocale } from '@/utils/locale'

/** 表单容器渲染位置id前缀 */
const NV_CRUD_FORM_WRAPPER_ID_PREFIX = 'nv-crud__form-wrapper__'
/** 弹窗表单的actionId前缀 */
const NV_CRUD_MODAL_ACTION_ID_PREFIX = 'nv-crud__modal-action__'
/** 抽屉表单的actionId前缀 */
const NV_CRUD_DRAWER_ACTION_ID_PREFIX = 'nv-crud__drawer-action__'

export function useForm(props: Props, emits: Emits, form: Ref<RowData>, formVisible: Ref<boolean>) {
  const UNIQUE_KEY = useId()
  const FORM_WRAPPER_ID = NV_CRUD_FORM_WRAPPER_ID_PREFIX + UNIQUE_KEY
  const MODAL_ACTION_ID = NV_CRUD_MODAL_ACTION_ID_PREFIX + UNIQUE_KEY
  const DRAWER_ACTION_ID = NV_CRUD_DRAWER_ACTION_ID_PREFIX + UNIQUE_KEY

  const isDrawer = computed(() => props.option.formWrapper?.type === 'drawer')

  const t = useLocale()

  const formTitle = computed(() => {
    if (props.option.formWrapper?.title) {
      return props.option.formWrapper.title(props.formMode)
    }
    else {
      return t.value.title[props.formMode]
    }
  })

  const formOption = computed<NvFormOption>(() => {
    console.debug('computed formOption')

    const fieldsEntiries: [string, NvFormItemOption][] = []
    function resolveFields(fields: Record<string, NvCrudFieldOption>) {
      for (const [field, fieldOption] of Object.entries(fields)) {
        if (fieldOption.children) {
          resolveFields(fieldOption.children)
        }
        else {
          const extraFieldOption = fieldOption[`${props.formMode}Form`]
          if (extraFieldOption === false) {
            continue
          }
          const _fieldOption = { ...fieldOption }
          if (typeof extraFieldOption === 'object') {
            Object.assign(_fieldOption, extraFieldOption)
          }
          _fieldOption.label = _fieldOption.label || fieldOption.title
          fieldsEntiries.push([field, _fieldOption])
        }
      }
    }
    let { formActions, fields } = props.option
    resolveFields(fields)

    const formFields = Object.fromEntries(fieldsEntiries)

    if (formActions !== false) {
      const teleportTo = isDrawer.value ? `#${DRAWER_ACTION_ID}` : `#${MODAL_ACTION_ID}`
      if (typeof formActions === 'object') {
        formActions = { ...formActions, teleportTo }
      }
      else {
        formActions = { teleportTo }
      }
    }

    return {
      ...props.option,
      formActions,
      size: props.size,
      fields: formFields,
    }
  })

  function onUpdateFormShow(value: boolean) {
    value ? openForm() : closeForm()
  }
  async function openForm() {
    await props.option.formWrapper?.onBeforeOpen?.(props.formMode)
    formVisible.value = true
  }
  async function closeForm() {
    await props.option.formWrapper?.onBeforeClose?.(props.formMode)
    formVisible.value = false
  }

  function handleSubmit(done: () => void) {
    const _done: FormDone = (close) => {
      done()
      if (close) {
        closeForm()
      }
    }
    if (props.formMode === 'add') {
      emits('row-save', { ...form.value }, _done)
    }
    else if (props.formMode === 'edit') {
      emits('row-update', { ...form.value }, _done)
    }
  }

  return {
    isDrawer, formVisible, formTitle, formOption,
    FORM_WRAPPER_ID, DRAWER_ACTION_ID, MODAL_ACTION_ID,
    onUpdateFormShow, openForm, closeForm, handleSubmit,
  }
}
